//
//  main.c
//  Marco
//
//  Created by admin on 2019/7/26.
//  Copyright © 2019 猫爷爷的酱醋茶. All rights reserved.
//

/*
 
 宏
 
 1. 语法格式：
    #define 宏名称 宏值
 
    1）在程序编译前，进行宏替换，如果宏是个表达式，也直接替换成表达式，而不是表达式的值。 //例：MacroExpression();
    2）宏值可以没有语法要求，但是在进行宏替换的时候，如果不符合语法规则，则会在替换代码中报错。
    3）如果宏值里面包含一个变量名，那么在使用这个宏之前，必须保证这个变量已经存在。//例：MacroExpression();
    4）无法通过赋值符号更改宏值，因为宏不是变量。
 
 2. 作用域:
    宏可以定义在任何地方，定义宏之后的代码都能使用宏。
 
    默认情况下，宏从定义的位置开始，一直到文件结束都可以使用，也可以通过
    #undef 宏名
    提前让指定的宏失效。
 
 3. 如果宏的后面有分号，那么宏值就包含分号，在宏替换的时候，也会把分号一同替换
 
 4. 为带参数的宏传值的时候，是本色传递。
 
    例：Max(n,m); //给宏Max传递的是n,m 而不是n,m的值
 
    因为在编译前，传递的变量还没被创。
 
 
 条件编译指令
    在预编译的时候，如果条件成立，就会将其中的C代码编译成二进制指令，
                 如果条件不成立，就不会将其中的C代码编译成二进制指令
 
 1. 语法格式：
    条件只能是宏，不能是变量。
    a）
        #if 条件
            C代码;
        #endif
 
    b）
        #if 条件
             C代码;
        #elif
             C代码;
        #else
             C代码;
        #endif
 
    c）如果定义了指定的宏，就将其中的C代码编译成二进制
        #ifdef 宏名
            C代码;
        #endif
 
      如果没有定义指定的宏，就将其中的C代码编译成二进制
        #ifndef 宏名
            C代码;
        #endif
 
 2.应用场景
    a）可以和调试Debug的输出语句相配合使用 例： #if DEBUG == 1
    b）一个头文件，无论被人为#include包含多少次，系统都只包含一次
         #ifndef 宏名
         #define 宏名
            C代码;
         #endif
 
 */
#include <stdio.h>
#define M 10 + 20 + 30
#define N n + n
#define Semicolon 10; //定义的宏名为 Semicolon 宏值为 ‘10;’
#define Max(a,b) a>b?a:b



//批量处理测试阶段的输出功能
#define PRINTF_DEBUG 0

#if PRINTF_DEBUG == 1
    #define LOG(val1,val2) printf(val1,val2)
#else
    #define LOG(val1,val2)
#endif

//宏表达式
void MacroExpression(void);

int main(int argc, const char * argv[]) {
    MacroExpression();
    return 0;
}

//#undef N

//宏表达式
void MacroExpression(void)
{
#ifdef M
    int n = 20 * M;
#endif
    

#ifndef Sex
    int m = N;
    int max = Max(n, m);
    int semicolon = 1 + Semicolon   //没报错的原因是宏值有分号
    
    printf("n = %d,m = %d,semicolon = %d\nmax = %d\n",n,m,semicolon,max);//n = 20 * 10 + 20 + 30 = 250
    
    LOG("m = %d\n", m);
#endif
}
